"use strict";
/*
  HTTPS服务器只提供WebSocket连接服务，所以每个请求只返回404。
  真正的Web请求由机器上的主服务器处理。
  如果愿意，可以在这里返回真正的HTML并提供Web内容。
  这里使用 express 来指定静态文件
*/

var express = require('express'),
  app = express();
var https = require('https');
var WebSocket = require('ws');
var WebSocketServer = WebSocket.Server;

var fs = require("fs");
var options = {
  key: fs.readFileSync("./key.pem"), //key文件路径
  cert: fs.readFileSync("./cert.pem") //crt文件路径
  }

app.use('/', express.static(__dirname + '/client')); //指定静态HTML文件的位置
var httpServer = https.createServer(options,app);

/*
  在分配给此示例的端口上启动 HTTP 服务器。
  这将很快转换为WebSocket端口。
*/
httpServer.listen(3000, function () {
  console.log("Server is listening on port 3000");
});

/*
  socket 服务器
  通过将 HTTP 服务器转换为一个 WebSocket 服务器
*/
var wsServer = new WebSocketServer({
  server: httpServer
});
if (!wsServer) {
  console.log("错误:无法创建WbeSocket服务器!");
}
/*
roomInfo = {};
  房间信息结构
  {
    房间号: {
      names: [],
      ws: []
    }
  }
*/
var roomInfo = {};
// 服务器被客户端连接
wsServer.on('connection', (ws) => {
  console.log("wsopen");

  var userInfo = {};

  // 接收客户端信息并把信息返回发送
  ws.on('message', (message) => {
    // 处理传入的数据。
    var sendToClients = true;
    var msg = JSON.parse(message);
    // 查看传入对象并根据其类型对其进行操作。传递未知的消息类型，因为它们可能用于实现客户端特性。带有“target”属性的消息仅通过该名称发送给用户。
    switch (msg.type) {
      // 加入
      case "join":
        {
          console.log("into join");
          var rid = msg.roomid;
          var uname = msg.myName;
          if (rid ==null| uname==null){
            
            console.log("出现了null用户");
            return;
            
          }
          var wsInfo = {
            wsname: ws,
            roomid: rid,
            userName: uname
          }
          
      // roomInfo {
      //   "roomid":{names[],
      //           clients[wsinfo :
      //                  {wsname:Object, roomid:Object, username.object}
      //                    ]
      //                 }
      // }
          if (roomInfo[rid]) {
            if (roomInfo[rid].names.indexOf(uname) == -1) {
              roomInfo[rid].names.push(uname);
              roomInfo[rid].clients.push(wsInfo);
              console.log(roomInfo[rid].clients.length);
            } else {
              // 该房间用户名已存在 表示二次加入 直接退出;
              var data = {
                type: 'error',
                roomid: msg.roomid,
                msg: '用户名已存在！'
              };
              wsServer.sendToOne(ws, data);
              return false;
            }
          } else { //如果不存在房间号,则先创建roominfo
            roomInfo[rid] = {};
            roomInfo[rid].names = [uname];
            roomInfo[rid].clients = [wsInfo]
          }
          // function 类名（形式参数列表）{
          //   this.属性名=参数；
          //   this.方法名=function(){

          //   }
          // // }
          // 加入成功 ===这个信息用来最后关闭链接===;
          userInfo = {
            roomid: rid,
            userName: uname
          };
          // 用户加入
          console.log(`${rid}房间加入新用户${uname}`);
          console.log(roomInfo);
          var msgString = {
            type: 'joined',
            roomid: rid,
            userList: roomInfo[rid].names,
            userName: uname
          };
          wsServer.broadcast(msgString);
          // 我们已经发出了正确的回应
          sendToClients = false;

          break;
        }
      //..............................................
      // sendMessage({
      //   roomid : '10',
      //   type: '__ice_candidate',  //对应的Server,似乎没有写出来;
      //   candidate: event.candidate,
      //   opponame : opponent,

      //   account: p2p.account
      // });
      case "__ice_candidate":

        {
          console.log("into __ice_candidate");

          var msgString = {
            type: '__ice_candidate',
            candidate: msg.candidate,
            roomid: msg.roomid,
            receiver: msg.opponame,
            account: msg.account,
            sender: msg.userName
          };
          // roomInfo[rid].clients.push(wsInfo);
          // var wsInfo = {
          //   wsname: ws,
          //   roomid: rid,
          //   userName: uname
          // }
          // console.log(msg);
          roomInfo[msg.roomid].clients.forEach(useropponent => {
            if (useropponent.uname == msg.receiver) {
              console.log("sent ice ");
              wsServer.sendToOne(useropponent.wsname, msgString);//找出接收方的ws;
            }

          });

          // 我们已经发出了正确的回应
          sendToClients = false;
          break;
        }
      // case "text":
      //   var p = document.createElement('p');
      //   p.innerText = msg.userName+': '+msg.text;
      //   textBox.append(p);
      //   break;
      //..............................................
      case "text":

        {
          console.log("into text");
          var msgString = {
            type: "text",
            text: msg.text,
            roomid: msg.roomid,
            userName: uname
          };
          wsServer.broadcast(msgString);
          // 我们已经发出了正确的回应
          sendToClients = false;
          break;
        }
      //..............................................
      // // 信令消息:这些消息用于在视频通话之前的谈判期间交换WebRTC信令信息。

      // sendMessage({
      //   roomid : '10',
      //   type: 'video-offer',
      //   sdp: peer.localDescription,
      //   receiver: accountname
      // sender:userName,
      // account:p2paccount

      case "video-offer":

        {
          console.log("into video-offer");
          // var msg = JSON.parse(msg.sdp);
          var msgString = {
            type: "video-offer",
            roomid: msg.roomid,
            sdp: msg.sdp,
            sender: msg.sender,
            receiver: msg.receiver,
            p2paccount: msg.account
          };
              // roomInfo[rid].clients.push(wsInfo);
          // var wsInfo = {
          //   wsname: ws,
          //   roomid: rid,
          //   userName: uname
          // }

          //从收的信息中查找此信息的目标接受者;
          roomInfo[msg.roomid].clients.forEach(useropponent => {
            console.log(useropponent.userName + "ooooo" +"" + msg.receiver);
            if (useropponent.userName == msg.receiver) {
              console.log("send video offer");
              wsServer.sendToOne(useropponent.wsname, msgString);//找出接收方的ws;
            }
          });
          sendToClients = false;
          break;
        }
      //.............................................


      case "video-answer":
        // sendMessage({
        //   roomid: '10',
        //   type: 'video-answer',
        //   sdp: peerList[msg.p2paccount].localDescription,
        //   sender:userName,
        //   receiver: msg.sender,
        //   p2paccount: msg.p2paccount
        // })

        {
          console.log("into video-answer");
          var msgString = {
            type: "video-answer",
            roomid: msg.roomid,
            sender: msg.sender,
            receiver: msg.receiver,
            sdp: msg.sdp,
            p2paccount: msg.p2paccount
          };
          roomInfo[msg.roomid].clients.forEach(useropponent => {
            if (useropponent.userName == msg.receiver) {
              wsServer.sendToOne(useropponent.wsname, msgString);//找出接收方的ws;
            }
          })
          sendToClients = false;
          break;
        }
    }})
    // 处理WebSocket“关闭”事件;这意味着用户已注销或已断开连接。
  ws.on('close', function (reason, description) {
      console.log("into ws.close");
      if (userInfo.userName) {
        var roomid = userInfo.roomid; 
        var userName = userInfo.userName;
          // 首先，从连接列表中删除连接。
          // roomInfo[rid].clients.push(wsInfo);
          // var wsInfo = {
          //   wsname: ws,
          //   roomid: rid,
          //   userName: uname
          // }
        roomInfo[roomid].clients = roomInfo[roomid].clients.filter(v => v.userName !== userName);
        roomInfo[roomid].names = roomInfo[roomid].names.filter(v => v !== userName);
        // 用户退出
        console.log(`通知房间${roomid}的用户${userName}退出！`);
        console.log(roomInfo);
        wsServer.broadcast({
          type: "disconnected",
          roomid: roomid,
          account: userName
        });
      }
            // 最后关闭本链接; 
      ws.close();

  })
  
})

wsServer.broadcast = function (data) {
    var roomid = data.roomid;
    console.log("into broadcast  ");
    var msgString = JSON.stringify(data);
    
    // console.log("check" + JSON.stringify(roomInfo[roomid]));
    roomInfo[roomid].clients.forEach(function (client) {
      console.log("into sending..........");
          // roomInfo[rid].clients.push(wsInfo);
          // var wsInfo = {
          //   wsname: ws,
          //   roomid: rid,
          //   userName: uname
          // }
      client.wsname.send(msgString);
    });
  };
  // 提示自己
wsServer.sendToOne = function (client, data) {
    var msgString = JSON.stringify(data);
    client.send(msgString);
  }
